package com.google.gsaguide;

import android.annotation.TargetApi;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;

import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.google.gsaguide.DAO.AmbassadorDAO;
import com.google.gsaguide.gplusbridge.GPlusRequestHelper;
import com.google.gsaguide.gplusbridge.OnGPlusRequestListener;
import com.google.gsaguide.gsa.Ambassador;
import com.google.gsaguide.otherlibs.SystemBarTintManager;
import com.google.gsaguide.otherlibs.WebUtils;
import com.google.gsaguide.volley.AppController;

import org.json.JSONObject;

import java.util.HashMap;

public class SplashActivity extends ActionBarActivity implements Response.ErrorListener, Response.Listener<String>, OnGPlusRequestListener {

    // TODO: Need to optimize and comment this code.

    public static final String SPLASH_SCREEN = "splash";
    private final String DEBUG_TAG = SplashActivity.class.getSimpleName();
    private final boolean DEBUG = true;
    private final String DATA_URL = "http://felipeporge.com/gsa/get_data.php";
    private final int WAIT_TIME = 3000; //in milliseconds
    private final int MAX_TIME_CYCLES = 40;
    private ImageView mSquareLoadingLeft;
    private ImageView mSquareLoadingRight;
    private SharedPreferences sPrefs;
    private AmbassadorDAO mAmbDB;
    private HashMap<String, Ambassador> mAmbassadorMap;
    private HashMap<String, Boolean> mAmbassadorUpdated;
    private GPlusRequestHelper mGPlusAsyncConn;
    private int mTimeCycles = 0;
    private Handler mUpdateHandler = new Handler();
    private DrawerLayout mDrawer;
    private FrameLayout.LayoutParams mDrawerParams;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_splash);

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
            mDrawer = (DrawerLayout) findViewById(R.id.splash_base_layout);
            mDrawerParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);

            setTranslucentStatus(true);
            SystemBarTintManager tintManager = new SystemBarTintManager(this);
            tintManager.setStatusBarTintEnabled(true);
            tintManager.setStatusBarTintColor(getResources().getColor(R.color.GoogleBlue));

            mDrawerParams.setMargins(0, getStatusBarHeight(), 0, 0);
            mDrawer.setLayoutParams(mDrawerParams);
        }

        mSquareLoadingLeft = (ImageView) this.findViewById(R.id.splash_loading_left);
        mSquareLoadingRight = (ImageView) this.findViewById(R.id.splash_loading_right);

        startLoadingAnimation();

        sPrefs = getSharedPreferences("settings", 0);
        if (!sPrefs.getBoolean(SPLASH_SCREEN, false)) {
            if (WebUtils.isConnected(this))
                getAmbassadors();
            else {
                System.exit(0);
            }
        } else {
            /**
             * TODO: Quando o usuário entrar no app e estiver com conexão ativa, atualizar as informações
             * o app deve verificar se existe algum novo usuário que ainda não foi adicionado ao banco de
             * dados.
             */
            if (WebUtils.isConnected(this))
                getAmbassadors();
            else
                finish();
        }
    }

    private void startLoadingAnimation() {

        Animation leftToRight = new TranslateAnimation(
                Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_PARENT, 1.4F,
                Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_SELF, 0.0F);

        leftToRight.setDuration(2500);
        leftToRight.setFillAfter(true);
        leftToRight.setRepeatCount(Animation.INFINITE);

        Animation rightToLeft = new TranslateAnimation(
                Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_PARENT, -1.4F,
                Animation.RELATIVE_TO_SELF, 0.0F, Animation.RELATIVE_TO_SELF, 0.0F);

        rightToLeft.setDuration(2500);
        rightToLeft.setFillAfter(true);
        rightToLeft.setRepeatCount(Animation.INFINITE);

        mSquareLoadingLeft.startAnimation(leftToRight);
        mSquareLoadingRight.startAnimation(rightToLeft);
    }

    public void getAmbassadors() {
        mAmbDB = AmbassadorDAO.getInstance(this);
        mGPlusAsyncConn = new GPlusRequestHelper(this, this);

        StringRequest stringRequest = new StringRequest(DATA_URL, this, this);
        stringRequest.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS,
                5, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        AppController.getInstance().addToRequestQueue(stringRequest);
    }

    @Override
    public void onResponse(String result) {
        try {
            result = new String(result.getBytes("ISO-8859-1"), "UTF-8");
            mAmbassadorMap = new HashMap<String, Ambassador>();
            mAmbassadorUpdated = new HashMap<String, Boolean>();

            if (DEBUG)
                Log.w(DEBUG_TAG, "------------>>> Step 1: FelipePorge.com data received. <<<------------");

            String[] jStrings = result.split("#");

            for (String str : jStrings) {
                JSONObject j = new JSONObject(str.substring(1));
                String id = j.getString("id");
                if (!mAmbDB.exists(id)) {
                    mGPlusAsyncConn.getInfo(id);
                    mAmbassadorMap.put(id,
                            new Ambassador(id, j.getString("university"), j.getString("location")));
                    mAmbassadorUpdated.put(id, false);
                }
            }

            mUpdateHandler.postDelayed(mTask, WAIT_TIME);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onErrorResponse(VolleyError volleyError) {
        if (DEBUG) {
            Log.w(DEBUG_TAG, "------------>>> Step 1: FelipePorge.com data request failed. <<<------------");
            Log.w(DEBUG_TAG, volleyError.getMessage().toString());
        }
    }

    private Runnable mTask = new Runnable() {
        @Override
        public void run() {
            boolean status = true;
            for (boolean b : mAmbassadorUpdated.values()) {
                if (!b) {
                    status = false;
                    break;
                }
            }

            if (!status) {
                if (mTimeCycles < MAX_TIME_CYCLES) {
                    mTimeCycles++;
                    mUpdateHandler.postDelayed(mTask, 500);
                } else {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(), "Timeout Error", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            } else {
                if (DEBUG) {
                    for (Ambassador amb : mAmbassadorMap.values())
                        Log.w("--------->> Amb. Id: ", amb.getId());
                }

                SharedPreferences.Editor editor = sPrefs.edit();
                editor.putBoolean(SPLASH_SCREEN, true);
                editor.commit();
                mAmbDB.close();
                finish();
            }
        }
    };

    @Override
    public void onPostExecute(JSONObject response, int errorCode) {
        if (errorCode == GPlusRequestHelper.NO_ERROR) {
            try {
                Ambassador amb = mAmbassadorMap.get(response.getString("id"));
                //Ambassador amb = mAmbassadorMap.get(new String(response.getString("id").getBytes("ISO-8859-1"), "UTF-8"));
                //amb.setPhotoURL(response.getJSONObject("image").getString("url").replace("sz=50", "sz=200"));
                amb.setPhotoURL(response.getString("image"));
                amb.setName(response.getString("displayName"));
                mAmbDB.add(amb);
                mAmbassadorUpdated.put(response.getString("id"), true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            Log.w(DEBUG_TAG, "Error " + errorCode);
        }
    }

    @TargetApi(19)
    private void setTranslucentStatus(boolean on) {
        Window win = getWindow();
        WindowManager.LayoutParams winParams = win.getAttributes();
        final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
        if (on) {
            winParams.flags |= bits;
        } else {
            winParams.flags &= ~bits;
        }
        win.setAttributes(winParams);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        if ((mDrawerParams != null) && (mDrawer != null) && (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)) {
            mDrawerParams.setMargins(0, getStatusBarHeight(), 0, 0);
            mDrawer.setLayoutParams(mDrawerParams);
        }
    }

    public int getStatusBarHeight() {
        int result = 0;
        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            result = getResources().getDimensionPixelSize(resourceId);
        }
        return result;
    }


}
